<template>
  <div class="rolelist">
    <div class="inner-container container">
      <div class="filter-container flex-row">
        <div class="flex-col-3 input-box">
          <el-input
            v-model="queryParams.role"
            placeholder="请输入角色"
          ></el-input>
        </div>
        <div class="flex-col-3 input-box">
          <el-select v-model="queryParams.status" placeholder="请选择">
            <el-option
              v-for="item in options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </div>
        <div class="btn-box">
          <el-button type="primary" icon="el-icon-search" plain @click="search" v-permission="{ action: 'view', effect: 'disabled' }"
            >搜索</el-button
          >
        </div>
      </div>
      <el-table
        :data="tableData"
        border
        v-loading="loading"
        :header-cell-style="{
          background: 'var(--primary-color)',
          color: 'var(--text-sidebar-hover-color)',
        }"
      >
        <!-- 展开列 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <el-row v-for="(item, index) in scope.row.children" :key="index">
              <el-col class="must" :span="5">
                <el-tag
                  class="tag"
                  closable
                  type="primary"
                  @close="delRowAll(scope.row.id, item.id)"
                  >{{ item.name }}</el-tag
                >
                <i class="el-icon-caret-right"></i>
              </el-col>
              <el-col :span="19" v-if="item.children">
                <el-row v-for="(child, index) in item.children" :key="index">
                  <el-col class="must" :span="6">
                    <el-tag
                      class="tag"
                      closable
                      type="success"
                      @close="delRowRight(scope.row.id, child.id)"
                      >{{ child.name }}</el-tag
                    >
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <el-col class="must" :span="18">
                    <el-tag
                      class="tag"
                      closable
                      type="warning"
                      @close="delRowPermission(scope.row.id, child.id, right.permissionId)"
                      v-for="(right, index) in child.rights"
                      :key="index"
                      >{{ right.permission }}</el-tag
                    >
                  </el-col>
                </el-row>
              </el-col>
              <el-col :span="19" v-else>
                <el-row>
                  <el-col class="must" :span="6"></el-col>
                  <el-col class="must" :span="18">
                    <el-tag
                      class="tag"
                      closable
                      type="warning"
                      @close="delRowPermission(scope.row.id, item.id, right.permissionId)"
                      v-for="(right, index) in item.rights"
                      :key="index"
                      >{{ right.permission }}</el-tag
                    >
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
            <span
              style="text-align: center; display: block; width: 100%"
              v-if="scope.row.children == null"
              >未分配权限</span
            >
          </template>
        </el-table-column>

        <!-- 索引列 -->
        <el-table-column
          type="index"
          label="ID"
          align="center"
        ></el-table-column>
        <el-table-column
          label="角色名称"
          prop="role"
          align="center"
        ></el-table-column>
        <el-table-column
          label="角色描述"
          prop="description"
          align="center"
        ></el-table-column>
        <el-table-column label="操作" width="300px" align="center">
          <template slot-scope="scope">
            <el-button
              plain
              type="warning"
              icon="el-icon-setting"
              v-permission="{ action: 'update', effect: 'disabled' }"
              @click="showSetRightDialog(scope.row)"
              >分配权限</el-button
            >
            <el-popconfirm
              title="确定删除吗？"
              @confirm="handleDeleteRow(scope.row.id)"
            >
              <el-button
                class="delete"
                icon="el-icon-delete"
                plain
                type="danger"
                slot="reference"
                v-permission="{ action: 'delete', effect: 'disabled' }"
                >删除</el-button
              >
            </el-popconfirm>
          </template>
        </el-table-column>
        <template slot="empty">
          <el-empty :image-size="200" description="暂无数据"></el-empty>
        </template>
      </el-table>
      <!-- 分配权限的对话框 -->
      <el-dialog
        title="分配权限"
        :visible.sync="dialogFormVisible"
        width="50%"
        @close="cancel"
      >
        <div class="right-option-wrap">
          <div class="other-select">
            <div class="input-box" v-for="item in rightslist" :key="item.id">
              <div class="parent-node">
                <div class="outer">
                  <input
                    type="checkbox"
                    v-model="submitData.rights"
                    v-if="!item.exist"
                    :value="item.id"
                    @change="selectNodeLevelOne($event, item)"
                  />
                  {{ item.name }}
                </div>
                <div class="wrapper" v-if="item.children">
                  <div
                    class="child-node"
                    v-for="child in item.children"
                    :key="child.id"
                  >
                    <div class="outer">
                      <input
                        type="checkbox"
                        v-model="submitData.rights"
                        :value="child.id"
                        v-if="!child.exist"
                        @change="selectNodeLevelTwo($event, item, child)"
                      />
                      {{ child.name }}
                    </div>
                    <div
                      class="permission-node"
                      v-for="(permission, index) in child.rights"
                      :key="index"
                    >
                      <div class="outer">
                        <input
                          type="checkbox"
                          v-model="submitData.permissions"
                          :value="`${permission.rightId}:${permission.permissionId}`"
                          @change="selectParent($event, item, child)"
                        />
                        {{ permission.permission }}
                      </div>
                    </div>
                  </div>
                </div>
                <div class="wrapper" v-else>
                  <div
                    class="child-node"
                    v-for="(permission, index) in item.rights"
                    :key="index"
                  >
                    <div class="outer">
                      <input
                        type="checkbox"
                        v-model="submitData.permissions"
                        :value="`${permission.rightId}:${permission.permissionId}`"
                        @change="selectParent($event, item)"
                      />
                      {{ permission.permission }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary" @click="submit">确 定</el-button>
        </span>
      </el-dialog>

      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 30, 40]"
        :page-size="queryParams.pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
      >
      </el-pagination>
    </div>
  </div>
</template>

<script>
import {
  roleRightPageQuery,
  grantRoleRightPermission,
  delRowRight,
  delRoleAllRight,
  delRowPermission,
  delRowRightGroup,
} from '@/api/role'
import { rightEffectiveOptions } from '@/api/right'
import { getTableData, handleVoidMethod } from '@/api/table'
export default {
  data() {
    return {
      options: [
        {
          value: -1,
          label: '全部',
        },
        {
          value: 0,
          label: '禁用',
        },
        {
          value: 1,
          label: '启用',
        },
      ],
      tableData: [],
      rightslist: [],
      multipleSelection: [],
      queryParams: {
        role: '',
        status: -1,
        page: 1,
        pageSize: 10,
      },
      rules: {
        role: [{ required: true, message: '请输入角色', trigger: 'blur' }],
      },
      total: 0,
      state: false,
      loading: false,
      imageUrl: '',
      currentPage: 1,
      labelPosition: 'right',
      dialogFormVisible: false,
      // 所有权限的数据
      rightslist: [],
      submitData: {
        roleId: '',
        rights: [],
        permissions: [],
      },
    }
  },
  created() {
    this.getTableData()
  },
  methods: {
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`)
      this.queryParams.pageSize = val
      this.getTableData()
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`)
      this.queryParams.page = val
      this.getTableData()
    },
    handleSelectionChange(val) {
      this.multipleSelection = []
      val.forEach((item) => {
        const { id } = item
        this.multipleSelection.push(id)
      })
    },
    handleDeleteRow(id) {
      console.log(id)
      handleVoidMethod(this, '删除成功', '删除失败', delRoleAllRight(id))
    },
    selectNodeLevelOne(e, levelOne) {
      if (levelOne.children) {
        let children = levelOne.children.map((item) => item.id)
        if (e.target.checked) {
          children.forEach((item) => this.submitData.rights.push(item))
        } else {
          children.forEach((item) => {
            if (this.submitData.rights.indexOf(item) !== -1) {
              this.submitData.rights.splice(this.submitData.rights.indexOf(item), 1)
            }
          })
          let delArr = []
          this.submitData.permissions.forEach((item) => {
            children.forEach((levelTwo) => {
              if (parseInt(item.split(':')[0]) === levelTwo) {
                delArr.push(item)
              }
            })
          })
          delArr.forEach((item) => {
            this.submitData.permissions.splice(
              this.submitData.permissions.indexOf(item),
              1
            )
          })
        }
      } else {
        if (!e.target.checked) {
          let delArr = []
          this.submitData.permissions.forEach((item) => {
            if (parseInt(item.split(':')[0]) === levelOne.id) {
              delArr.push(item)
            }
          })
          delArr.forEach((item) => {
            this.submitData.permissions.splice(
              this.submitData.permissions.indexOf(item),
              1
            )
          })
        }
      }
    },
    selectNodeLevelTwo(e, levelOne, levelTwo) {
      if (e.target.checked) {
        if (this.submitData.rights.indexOf(levelOne.id) === -1) {
          this.submitData.rights.push(levelOne.id)
        }
      } else {
        let isRemove = this.submitData.rights.every((item) => {
          return levelOne.children.map((item) => item.id).indexOf(item) === -1
        })
        let delArr = this.submitData.permissions.filter((item) => {
          return parseInt(item.split(':')[0]) === levelTwo.id
        })
        delArr.forEach((item) => {
          this.submitData.permissions.splice(
            this.submitData.permissions.indexOf(item),
            1
          )
        })
        if (isRemove) {
          this.submitData.rights.splice(
            this.submitData.rights.indexOf(levelOne.id),
            1
          )
        }
      }
    },
    selectParent(e, wrap, parent) {
      if (e.target.checked) {
        if (this.submitData.rights.indexOf(wrap.id) === -1) {
          this.submitData.rights.push(wrap.id)
        }
        if (parent) {
          if (this.submitData.rights.indexOf(parent.id) === -1) {
            this.submitData.rights.push(parent.id)
          }
          return
        }
        if (this.submitData.rights.indexOf(wrap.id) === -1) {
          this.submitData.rights.push(wrap.id)
        }
      }
    },
    // 展示分配权限的对话框
    showSetRightDialog(role) {
      this.dialogFormVisible = true
      this.submitData.roleId = role.id
      this.getRightOptions(role.id)
    },
    cancel() {
      this.submitData = {
        roleId: '',
        rights: [],
        permissions: [],
      }
      this.dialogFormVisible = false
    },
    submit() {
      handleVoidMethod(this, '授权成功', '授权失败', grantRoleRightPermission(this.submitData), this.cancel)
    },
    delRowAll(roleId, rightId) {
      console.log(roleId, rightId);
      handleVoidMethod(this, '删除成功', '删除失败', delRowRightGroup({ roleId, rightId }))
    },
    delRowRight(roleId, rightId) {
      handleVoidMethod(this, '删除成功', '删除失败', delRowRight({ roleId, rightId }))
    },
    delRowPermission(roleId, rightId, permissionId) {
      handleVoidMethod(this, '删除成功', '删除失败', delRowPermission({ roleId, rightId, permissionId }))
    },
    getTableData() {
      this.loading = true
      getTableData(this, roleRightPageQuery(this.queryParams))
    },
    getRightOptions(roleId) {
      rightEffectiveOptions(roleId).then((res) => {
        this.rightslist = res.data
      })
    },
    search() {
      this.getTableData()
    },
  },
}
</script>

<style lang="less" scoped>
.rolelist {
  padding: 10px;
  box-sizing: border-box;
  .filter-container {
    flex-wrap: wrap;
    box-sizing: border-box;
    margin-bottom: 20px;
  }
  .inner-container {
    box-sizing: border-box;
    border-radius: 5px;
    padding: 20px;
    background-color: var(--bg-primary-color);
    transition: var(--tran-01);
  }
  .input-box {
    margin-right: 10px;
  }
}
.el-select {
  width: 100%;
}
/deep/ .el-dialog {
  background: var(--bg-primary-color);
  transition: var(--tran-01);
}
/deep/ .el-dialog__title {
  color: var(--text-normal-color) !important;
  transition: var(--tran-01);
}
/deep/ .el-form-item__label {
  color: var(--text-normal-color) !important;
  transition: var(--tran-01);
}
.el-form {
  display: flex;
  flex-wrap: wrap;
}
/deep/ .el-form-item__label {
  text-align: center !important;
}
.el-pagination {
  margin-top: 20px;
}

/deep/ .el-pagination button {
  background-color: var(--bg-primary-color);
  transition: var(--tran-01);
}
/deep/ .el-pager li {
  background-color: var(--bg-primary-color);
  transition: var(--tran-01);
}
/deep/ .el-pager li.active {
  color: var(--primary-color);
  background-color: var(--bg-primary-color);
  transition: var(--tran-01);
}
/deep/ .el-pagination__total {
  color: var(--text-normal-color);
  transition: var(--tran-01);
}
/deep/ .el-pagination__jump {
  color: var(--text-normal-color);
  transition: var(--tran-01);
}
.btn-box {
  display: flex;
  flex-wrap: wrap;
}
/deep/ .el-button {
  flex-grow: 1;
}
/deep/ .el-input .el-input__inner {
  color: var(--text-normal-color);
  background-color: var(--history-color) !important;
  transition: var(--tran-01);
}

/deep/ .el-select-dropdown {
  background-color: var(--history-color) !important;
}
/deep/ .el-table,
/deep/ .el-table__expanded-cell {
  background-color: transparent !important;
}

/deep/ .el-table__body-wrapper.is-scrolling-left::-webkit-scrollbar,
/deep/ .el-table__body-wrapper.is-scrolling-right::-webkit-scrollbar,
/deep/ .el-table__body-wrapper.is-scrolling-middle::-webkit-scrollbar {
  height: 5px;
}
/deep/ .el-table__body-wrapper.is-scrolling-left::-webkit-scrollbar-thumb,
/deep/ .el-table__body-wrapper.is-scrolling-right::-webkit-scrollbar-thumb,
/deep/ .el-table__body-wrapper.is-scrolling-middle::-webkit-scrollbar-thumb {
  background: #ccc; // 滑块颜色
  border-radius: 6px; // 滑块圆角
}
/deep/ .el-table__body-wrapper.is-scrolling-left::-webkit-scrollbar-track,
/deep/ .el-table__body-wrapper.is-scrolling-right::-webkit-scrollbar-track,
/deep/ .el-table__body-wrapper.is-scrolling-middle::-webkit-scrollbar-track {
  border-radius: 10px; // 轨道圆角
  background-color: #fff // 轨道颜色 ;
}
/deep/ .el-table tr {
  color: var(--text-normal-color);
  background-color: var(--history-color);
  transition: var(--tran-01);
}

/deep/ .el-table__body tr:hover > td {
  background-color: #a69ff5 !important;
  color: var(--text-sidebar-hover-color);
}

/deep/ .el-tree__empty-block {
  background-color: var(--bg-primary-color);
}

.must {
  margin: 10px 0;
  text-align: center;
  .tag {
    margin-right: 10px;
  }
}

.right-option-wrap {
  height: 300px;
  overflow: auto;
  box-sizing: border-box;
  color: var(--text-normal-color);
  .selete-all {
    display: flex;
    align-items: center;
    margin-bottom: 4px;
  }
  .other-select {
    width: 100%;
  }
  .outer {
    display: flex;
    align-items: center;
    margin-bottom: 6px;
  }
  .parent-node {
    box-sizing: border-box;
    .child-node {
      margin-left: 20px;
      .permission-node {
        margin-left: 20px;
      }
    }
  }
  &::-webkit-scrollbar {
    height: 5px;
    width: 5px;
  }
  &::-webkit-scrollbar-thumb {
    background: #ccc; // 滑块颜色
    border-radius: 6px; // 滑块圆角
  }
  &::-webkit-scrollbar-track {
    border-radius: 10px; // 轨道圆角
    background-color: #fff // 轨道颜色 ;
  }
}
.edit {
  margin-right: 10px;
}
.delete {
  margin-left: 10px;
}
</style>
